package com.jargonee.activities;

import java.util.Hashtable;

import com.jargonee.activities.R;
import com.jargonee.threads.BackendThread;
import com.jargonee.threads.BackendThread.BackendThreadMessages;
import com.jargonee.threads.BackendThread.BackendThreadModes;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Color;
import android.location.Address;
import android.location.Geocoder;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnFocusChangeListener;
import android.view.View.OnKeyListener;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.TextView;

public class JargoneeLauncher extends Activity {

	// different types of dialogs
	static final int SEARCH_RADIUS_DIALOG = 0;
	static final int LOCATION_PROGRESS_DIALOG = 1;
	static final int ERROR_DIALOG = 2;

	// different views representing search radius
	static final int CITY_RADIUS_VIEW = 0;
	static final int STATE_RADIUS_VIEW = 1;
	static final int COUNTRY_RADIUS_VIEW = 2;

	// view components
	private EditText searchText;
	private ImageButton searchButton;
	private TextView cityWideTextView;
	private TextView stateWideTextView;
	private TextView countryWideTextView;
	private TextView visibleRadiusTextView;
	private InputMethodManager softKeyboard;
	private LocationManager locationManager;

	private int searchRadiusDialogSelectedItem = 0;
	
	// Define the Handler that receives messages from the search thread and update the progress
    final Handler handler = new Handler() { public void handleMessage(Message msg) { handleJargoneeLauncherMessage(msg);}};


	/**
	 * Called when the activity is first created
	 */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.jargonee_launcher);

		// get view component references
		searchText = (EditText) findViewById(R.id.SearchBox);
		searchButton = (ImageButton) findViewById(R.id.SearchButton);
		cityWideTextView = (TextView) findViewById(R.id.CityWideTextView);
		stateWideTextView = (TextView) findViewById(R.id.StateWideTextView);
		countryWideTextView = (TextView) findViewById(R.id.CountryWideTextView);
		visibleRadiusTextView = cityWideTextView;

		// get system services
		softKeyboard = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
		locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

		// give radius view focus so it only has to be selected once
		visibleRadiusTextView.requestFocus();

		// search box key listener
		searchText.setOnKeyListener(new OnKeyListener() {
			public boolean onKey(View v, int keyCode, KeyEvent event) {
				
				// When Enter is pressed hide softkeyboard and lose focus
				if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER)) {
					softKeyboard.hideSoftInputFromWindow(v.getWindowToken(), 0);
					visibleRadiusTextView.requestFocus();
					return true;
				}
				return false;
			}
		});

		// search box change listener
		searchText.setOnFocusChangeListener(new OnFocusChangeListener() {
			public void onFocusChange(View v, boolean hasFocus) {

				// if gets focus and default search string is there remove it and set text to black
				if (hasFocus && ((EditText) v).getText().toString().
						equalsIgnoreCase(getResources().getString(R.string.seach_default))) {
					searchText.setText("", TextView.BufferType.EDITABLE);
					searchText.setTextColor(Color.BLACK);
				}
			}
		});

		// start searching when search button is clicked
		searchButton.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				
				if(searchText.getText().toString().length() < 1 || searchText.getTextColors().getDefaultColor() == Color.LTGRAY) {
					Bundle bundle = new Bundle();
					bundle.putString("message", "You must enter a term to search for.");
					showDialog(ERROR_DIALOG, bundle);
					return;
				}
				
				showDialog(LOCATION_PROGRESS_DIALOG, null);
				softKeyboard.hideSoftInputFromWindow(v.getWindowToken(), 0);
				getLocation();
			}
		});

		// On click listener to show dialog to select from different radiuses
		View.OnClickListener searchRadiusClickLisener = new OnClickListener() {
			public void onClick(View v) {
				showDialog(SEARCH_RADIUS_DIALOG, null);
			}
		};
		cityWideTextView.setOnClickListener(searchRadiusClickLisener);
		stateWideTextView.setOnClickListener(searchRadiusClickLisener);
		countryWideTextView.setOnClickListener(searchRadiusClickLisener);
	}
	
	/**
	 * Handle message return from threads
	 * @param msg Message returned from thread
	 */
	private void handleJargoneeLauncherMessage(Message msg) {
		dismissDialog(LOCATION_PROGRESS_DIALOG);
    	switch((BackendThreadMessages)msg.getData().getSerializable("message type")) {
    		case SearchSuccessful:
    			break;
    		case NoLocationService:
    			showDialog(ERROR_DIALOG, msg.getData());
    			break;
    		case TroubleGettingLocation:
    			showDialog(ERROR_DIALOG, msg.getData());
    			break;
    		case BadInternetConnection:
    			showDialog(ERROR_DIALOG, msg.getData());
    			break;
    		case TroubleGettingResults:
    			showDialog(ERROR_DIALOG, msg.getData());
    			break;
    		case LocationFound:
    			startSearch((Address)msg.obj);
    			break;
    			
    		default:
    			Bundle bundle = new Bundle();
    			bundle.putString("message", "results received");
    			showDialog(ERROR_DIALOG, bundle);
    			break;
    	}
	}

	/**
	 * Creates dialogs
	 */
	@Override
	protected Dialog onCreateDialog(int id, Bundle args) {
		Dialog dialog = null;
		AlertDialog.Builder builder = new AlertDialog.Builder(this);
		switch (id) {
		case SEARCH_RADIUS_DIALOG:
			// build dialog with radio buttons for selecting search radius
			builder.setTitle("Pick a search radius");
			builder.setSingleChoiceItems(getResources().getStringArray(R.array.search_radius_selection_array),
					searchRadiusDialogSelectedItem, new DialogInterface.OnClickListener() {
						public void onClick(DialogInterface dialog, int item) {
							// save selected item & show appropriate view
							cityWideTextView.setVisibility(View.GONE);
							stateWideTextView.setVisibility(View.GONE);
							countryWideTextView.setVisibility(View.GONE);
							switch (item) {
							case CITY_RADIUS_VIEW:
								visibleRadiusTextView = cityWideTextView;
								cityWideTextView.setVisibility(View.VISIBLE);
								break;
							case STATE_RADIUS_VIEW:
								visibleRadiusTextView = stateWideTextView;
								stateWideTextView.setVisibility(View.VISIBLE);
								break;
							case COUNTRY_RADIUS_VIEW:
								visibleRadiusTextView = countryWideTextView;
								countryWideTextView.setVisibility(View.VISIBLE);
								break;
							default:
								break;
							}
							searchRadiusDialogSelectedItem = item;
							dismissDialog(SEARCH_RADIUS_DIALOG);
							visibleRadiusTextView.requestFocus();
						}
					});
			dialog = builder.create();
			break;
		case LOCATION_PROGRESS_DIALOG:
			dialog = ProgressDialog.show(JargoneeLauncher.this, "", "Loading Current Address. Please wait...", true);
			break;
		case ERROR_DIALOG:
			// build alert dialog with error message and ok button
			builder.setMessage(args.getString("message"))
		       .setCancelable(false)
		       .setNeutralButton("Ok", new DialogInterface.OnClickListener() {
		           public void onClick(DialogInterface dialog, int id) {
		        	   dismissDialog(ERROR_DIALOG);
		           }
		       });
			dialog = builder.create();
			break;
		default:
			break;
		}

		return dialog;
	}

	/**
	 * Start search for buzzword based on address
	 * @param address
	 */
	private void startSearch(Address address) {
		// setup intent and start it
		Intent jargoneeSearch = new Intent(this, JargoneeSearch.class);
		jargoneeSearch.putExtra("word", searchText.getText().toString());
		jargoneeSearch.putExtra("radius", searchRadiusDialogSelectedItem);
		jargoneeSearch.putExtra("address", address);
		startActivity(jargoneeSearch);
		
		// show search button just in case user come back
		//searchButton.setVisibility(View.VISIBLE);
		//searchButton.requestFocus();
	}
	
	/**
	 * Start buzzwords search in a separate thread
	 */
	private void getLocation() {
		
		// package extra parameters needed
		Geocoder geocoder = new Geocoder(this);
		Hashtable<String,Object> extraParams = new Hashtable<String, Object>();
		extraParams.put("locationManager", locationManager);
		extraParams.put("geocoder", geocoder);
		
		// kickoff thread
		BackendThread thread = new BackendThread(handler, BackendThreadModes.RetrieveCurrentAddress, extraParams);
		thread.start();
	}
}